package name.flurl.android.tt_news4android;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.UUID;

import name.flurl.android.tt_news4android.SimpleGestureFilter.SimpleGestureListener;
import name.flurl.android.tt_news4android.Tt_news4AndroidApplication.CONSTANTS;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.HeaderViewListAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.ViewFlipper;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CompoundButton.OnCheckedChangeListener;

public class NewsListActivity extends Activity implements SimpleGestureListener {
	private ArrayList<NewsAdapter> mNewsAdapter = new ArrayList<NewsAdapter>();
	private ArrayList<ListView> mListViews = new ArrayList<ListView>();
	private ArrayList<LinearLayout> mListFooters = new ArrayList<LinearLayout>();
	private SimpleGestureFilter mGestureDetector;
	private ViewFlipper mFlipper;
	private Animation mSlideLeftIn;
	private Animation mSlideLeftOut;
	private Animation mSlideRightIn;
	private Animation mSlideRightOut;
	private Tt_news4AndroidSharedPreferences mPreferences;
	private ArrayList<MenuItem> mSitesMenus = new ArrayList<MenuItem>();

	/** State of the activity */
	class State {
		public ArrayList<NewsAdapter> adapter = null;
		public int displayedView = 0;
	}

	// Define the Handler that receives messages from the thread and shows or
	// dismisses the loading dialog
	final Handler loadingDlgHandler = new Handler() {
		public void handleMessage(Message msg) {
			int action = msg.getData().getInt("action");
			switch (action) {
			case CONSTANTS.MSG_LOADING:
				// showDialog(CONSTANTS.LOADINGDLG);
				break;
			case CONSTANTS.MSG_LOADING_FINISHED:
				// dismissDialog(CONSTANTS.LOADINGDLG);
				break;
			case CONSTANTS.MSG_EOF:
				onNoMoreNewsAvailable();
			}

		}
	};

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// for setting the app icon
		requestWindowFeature(Window.FEATURE_LEFT_ICON);
		// the content has to be inflated before...
		setContentView(R.layout.news_list);
		// ...we can set the app icon
		getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
				R.drawable.icon);

		int viewToDisplay = 0;
		mPreferences = new Tt_news4AndroidSharedPreferences(PreferenceManager
				.getDefaultSharedPreferences(this));
		mFlipper = (ViewFlipper) findViewById(R.id.EventsListFlipper);

		firstRunSetup();

		final State state = (State) getLastNonConfigurationInstance();
		if (state != null) {
			mNewsAdapter = state.adapter;
			viewToDisplay = state.displayedView;
		}

		ArrayList<String[]> sites = ((Tt_news4AndroidApplication) getApplication())
				.getSites();

		for (int i = 0; i < sites.size(); i++) {
			try {
				final NewsAdapter adapter;
				if (mNewsAdapter.size() <= i) {
					String urlStr = sites.get(i)[1];
					adapter = new NewsAdapter(this, new URL(urlStr),
							loadingDlgHandler);
				} else {
					adapter = mNewsAdapter.get(i);
				}
				mNewsAdapter.add(adapter);
				ListView view = new ListView(this);

				LayoutInflater inflater = getLayoutInflater();
				LinearLayout footer = (LinearLayout) inflater.inflate(
						R.layout.load_more_list_footer, null);
				mListFooters.add(footer);
				view.addFooterView(footer);

				view.setAdapter(adapter);
				view.setOnItemClickListener(new OnItemClickListener() {

					@Override
					public void onItemClick(AdapterView<?> l, View v,
							int position, long id) {
						showNewsDetail(adapter.getItem(position));
					}

				});

				view.setOnScrollListener(new OnScrollListener() {
					private int priorFirst;

					@Override
					public void onScrollStateChanged(AbsListView view,
							int scrollState) {
					}

					@Override
					public void onScroll(AbsListView view,
							int firstVisibleItem, int visibleItemCount,
							int totalItemCount) {
						Log.i("tt_news ", "onScroll");
						if ((firstVisibleItem + visibleItemCount == totalItemCount)) {
							Log
									.i("tt_news ",
											"onScroll totalItemCount reached");
							// see if we have more results
							if (firstVisibleItem != priorFirst) {
								Log
										.i("tt_news ",
												"onScroll firstVisibleItem != priorFirst");
								priorFirst = firstVisibleItem;
								NewsListActivity.this.getAdapter()
										.loadMoreEvents();
							}
						}
					}
				});

				mListViews.add(view);
				mFlipper.addView(view);
			} catch (MalformedURLException e) {
				e.printStackTrace();
			}
		}

		mFlipper.setDisplayedChild(viewToDisplay);

		mSlideLeftIn = AnimationUtils.loadAnimation(this, R.anim.slide_left_in);
		mSlideLeftOut = AnimationUtils.loadAnimation(this,
				R.anim.slide_left_out);
		mSlideRightIn = AnimationUtils.loadAnimation(this,
				R.anim.slide_right_in);
		mSlideRightOut = AnimationUtils.loadAnimation(this,
				R.anim.slide_right_out);

		mGestureDetector = new SimpleGestureFilter(this, this);

		OnClickListener loadMoreBtnListener = new OnClickListener() {
			public void onClick(View v) {
				// Log.i("POGA Events click", "Load More");
				getAdapter().loadMoreEvents();
			}
		};

		// Button loadMoreBtn = (Button) findViewById(R.id.load_more);
		// loadMoreBtn.setOnClickListener(loadMoreBtnListener);

		setTitle();
		// registerForContextMenu(getListView());
		// fillData();
	}

	protected void onNoMoreNewsAvailable() {
		LinearLayout footer = mListFooters.get(mFlipper.getDisplayedChild());
		// save the height and set it later again, to prevent jumping list
		int h = footer.getHeight();
		ProgressBar progressBar = (ProgressBar) footer
				.findViewById(R.id.news_list_footer_progress);
		progressBar.setVisibility(View.GONE);
		TextView text = (TextView) footer
				.findViewById(R.id.news_list_footer_text);
		text.setText(R.string.no_more_news_msg);

		footer.setMinimumHeight(h);
	}

	private void firstRunSetup() {

		if (mPreferences.getBoolean("showFirstRunDlgPref", true)) {

			final Dialog dialog = new Dialog(this);
			dialog.setTitle(R.string.information);

			LinearLayout layout = new LinearLayout(this);
			layout.setOrientation(LinearLayout.VERTICAL);

			TextView msg = new TextView(this);
			msg.setText(R.string.first_run_msg);
			layout.addView(msg);

			CheckBox chk = new CheckBox(this);
			chk.setText(R.string.dont_show_again);
			chk.setChecked(!mPreferences
					.getBoolean("showFirstRunDlgPref", true));
			chk.setOnCheckedChangeListener(new OnCheckedChangeListener() {
				@Override
				public void onCheckedChanged(CompoundButton buttonView,
						boolean isChecked) {
					mPreferences.edit().putBoolean("showFirstRunDlgPref",
							!isChecked).commit();
				}
			});
			layout.addView(chk);

			Button btn = new Button(this);
			btn.setText(R.string.ok);
			btn.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					if (mPreferences.getString("UUIDPref", "") == "") {
						mPreferences.edit().putString("UUIDPref",
								UUID.randomUUID().toString()).commit();
					}
					dialog.dismiss();
				}
			});
			layout.addView(btn);

			dialog.setContentView(layout);
			dialog.show();
		}

	}

	@Override
	public Object onRetainNonConfigurationInstance() {
		Log.i("tt_news list activity", "onretainNonConfigurationState");
		State state = new State();
		state.adapter = mNewsAdapter;
		state.displayedView = mFlipper.getDisplayedChild();
		// state.forthcommingAdapter = mForthcommingAdapter;
		// state.nextAdapter = mPreviousAdapter;
		// state.period = mFlipper.getDisplayedChild() == 0 ?
		// CONSTANTS.FORTHCOMMING
		// : CONSTANTS.PREVIOUS;
		return state;
	}

	@Override
	public void onPause() {
		super.onPause();
		Log.i("tt_news list activity", "onPause");
		// dismissDialog(CONSTANTS.LOADINGDLG);
	}

	private void showNewsDetail(NewsEntry news) {
		Intent i = new Intent(this, NewsDetailActivity.class);
		i.putExtra("news", news);
		startActivityForResult(i, 0);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		ArrayList<String[]> sites = ((Tt_news4AndroidApplication) getApplication())
				.getSites();
		for (int i = 0; i < sites.size(); i++) {
			MenuItem mi = menu.add(0, i, 0, sites.get(i)[0]);
			mSitesMenus.add(mi);
			Log.i("tt_news onCreateOptionsMenu", "itemid: " + mi.getItemId());
		}

		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main_menu, menu);

		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent intent;
		for (int i = 0; i < mSitesMenus.size(); i++) {
			if (item.getItemId() == mSitesMenus.get(i).getItemId()) {
				final int viewToDisplay = i;
				int distance = mFlipper.getDisplayedChild() - i;
				final int leftDistance = distance > 0 ? distance : mFlipper
						.getChildCount()
						- Math.abs(distance);
				final int rightDist = mFlipper.getChildCount() - leftDistance;

				Log.i("tt_news menuclick", "distance: " + distance + " left: "
						+ leftDistance + " right: " + rightDist);

				final Handler h = new Handler();

				Runnable r = new Runnable() {
					@Override
					public void run() {
						Log.i("tt_news menuclick runnable", "running now");
						if (mFlipper.getDisplayedChild() != viewToDisplay) {
							if (rightDist <= leftDistance) {
								showNext(300);
								h.removeCallbacks(this);
								h.postDelayed(this, 500);
							} else {
								showPrevious(300);
								h.removeCallbacks(this);
								h.postDelayed(this, 500);
							}
						} else {
							h.removeCallbacks(this);
						}
					}
				};
				h.post(r);
				return true;
			}
		}

		// Handle item selection
		switch (item.getItemId()) {
		case R.id.menu_preferences:
			// Log.i("POGA Events click", "Show latest gallery menu clicked");
			intent = new Intent(this, PreferencesActivity.class);
			startActivity(intent);
			return true;
		default:
			// Log.i("POGA Events click", "something went wrong");
			return super.onOptionsItemSelected(item);
		}
	}

	private NewsAdapter getAdapter() {
		return (NewsAdapter) ((HeaderViewListAdapter) ((ListView) mFlipper
				.getCurrentView()).getAdapter()).getWrappedAdapter();
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent me) {
		this.mGestureDetector.onTouchEvent(me);
		return super.dispatchTouchEvent(me);
	}

	@Override
	public void onSwipe(int direction) {
		switch (direction) {
		case SimpleGestureFilter.SWIPE_RIGHT:
			showPrevious();
			break;
		case SimpleGestureFilter.SWIPE_LEFT:
			showNext();
			break;
		case SimpleGestureFilter.SWIPE_DOWN:
			break;
		case SimpleGestureFilter.SWIPE_UP:
			break;
		}
	}

	public void showNext() {
		showNext(CONSTANTS.DEF_SLIDE_DURATION);
	}

	public void showPrevious() {
		showPrevious(CONSTANTS.DEF_SLIDE_DURATION);
	}

	public void showNext(int duration) {
		if (mFlipper.getChildCount() > 1) {
			mSlideLeftIn.setDuration(duration);
			mSlideLeftOut.setDuration(duration);
			mFlipper.setInAnimation(mSlideLeftIn);
			mFlipper.setOutAnimation(mSlideLeftOut);
			mFlipper.showNext();
			setTitle();
		}
	}

	public void showPrevious(int duration) {
		if (mFlipper.getChildCount() > 1) {
			mSlideRightIn.setDuration(duration);
			mSlideRightOut.setDuration(duration);
			mFlipper.setInAnimation(mSlideRightIn);
			mFlipper.setOutAnimation(mSlideRightOut);
			mFlipper.showPrevious();
			setTitle();
		}
	}

	private void setTitle() {
		ArrayList<String[]> sites = ((Tt_news4AndroidApplication) getApplication())
				.getSites();
		if (sites.size() > 0) {
			super.setTitle(sites.get(mFlipper.getDisplayedChild())[0] + " - "
					+ getString(R.string.app_name));
		}
	}

	@Override
	public void onDoubleTap() {
	}

	protected Dialog onCreateDialog(int id) {
		Dialog dlg;
		switch (id) {
		case CONSTANTS.LOADINGDLG:
			dlg = new ProgressDialog(this);
			dlg.setOwnerActivity(this);
			((ProgressDialog) dlg)
					.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			((ProgressDialog) dlg).setMessage("Loading...");
			dlg.setCancelable(false);
			break;

		default:
			dlg = null;
		}
		return dlg;
	}

}